﻿using PLCS.Application.Contracts.EquipmentApp.Dtos;
using PLCS.Application.Contracts.StationApp;
using PLCS.Application.Contracts.StationApp.Dtos;
using PLCS.Domain;
using PLCS.Domain.Shared.Stations;
using PLCS.Domain.Stations;
using PLCS.Domain.Trays;
using System.Collections.Generic;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Repositories;

namespace PLCS.Application.StationApp;

public class StationAppService : CrudAppService<Station, StationDto, Guid, PagedResultRequestDto, StationEditDto>, IStationAppService
{
    private readonly IStationRepository _stationRepository;
    private readonly IRepository<Tray, Guid> _trayRepository;

    public StationAppService(IStationRepository repository, IRepository<Tray, Guid> trayRepository) : base(repository)
    {
        _stationRepository = repository;
        _trayRepository = trayRepository;
    }

    /// <summary>
    /// 根据工位名称查询工位
    /// </summary>
    /// <param name="name">工位名称</param>
    /// <returns>工位实体</returns>
    public async Task<StationDto> GetBySNameAsync(string name)
    {
        var model = await _stationRepository.GetStationByNumAsync(name);
        Check.NotNull(model, name, $"工位‘{name}’不存在");
        return ObjectMapper.Map<Station, StationDto>(model);
    }

    public async Task<IEnumerable<StationDto>> GetBySNameFuzzyAsync(string name)
    {
        var models = await _stationRepository.GetStationListAsync(x => x.StaNum.StartsWith(name));
        Check.NotNull(models, name, $"工位‘{name}’不存在");
        return ObjectMapper.Map<IEnumerable<Station>, IEnumerable<StationDto>>(models);
    }

    /// <summary>
    /// 批量插入工位
    /// </summary>
    /// <param name="stations"></param>
    /// <returns></returns>
    public async Task InsertListAsync(IEnumerable<StationEditDto> stations)
    {
        Check.NotNull(stations, "工位集合");
        if (!stations.Any())
            throw new Exception("集合不能为空");
        var list = ObjectMapper.Map<IEnumerable<StationEditDto>, IEnumerable<Station>>(stations);

        await _stationRepository.InsertManyAsync(list);
    }

    public async Task UpdateAsync(StationEditDto input)
    {
        var entity = await GetEntityByIdAsync(input.Id);
        await MapToEntityAsync(input, entity);
        await Repository.UpdateAsync(entity, autoSave: true);
    }

    public async Task DeleteAllAsync()
    {
        await _stationRepository.DeleteAllAsync();
    }

    public async Task<PagedResultDto<StationDto>> GetListBySearchAsync(PagedResultRequestDto input, string? stationNo, string? stationType)
    {
        await CheckGetListPolicyAsync();

        var query = await ReadOnlyRepository.WithDetailsAsync(x => x.Trays);

        query = query.OrderBy(x => x.StaNum);
        query = query.WhereIf(!string.IsNullOrEmpty(stationNo), x => x.StaNum == stationNo)
            .WhereIf(!string.IsNullOrEmpty(stationType), x => x.StationType == (StationType)Enum.Parse(typeof(StationType), stationType));
        var totalCount = await AsyncExecuter.CountAsync(query);

        query = ApplyPaging(query, input);

        var entities = await AsyncExecuter.ToListAsync(query);
        var entityDtos = await MapToGetListOutputDtosAsync(entities);

        return new PagedResultDto<StationDto>(
            totalCount,
            entityDtos
        );
    }
}